package com.onetech.adrewards.free.models;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.os.Bundle;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.onetech.adrewards.free.OneTech_ApplicationContext;
import com.onetech.adrewards.free.config.AppConfig.AdRewardKey;
import com.onetech.adrewards.free.config.AppConfig.Cache;
import com.onetech.adrewards.free.http.APIRequestResult;
import com.onetech.adrewards.free.http.ZuZuHttpRequest;
import com.onetech.adrewards.free.listener.AdRewardIF;
import com.onetech.adrewards.free.objects.AdDTO;
import com.onetech.adrewards.free.objects.AdDTO2;
import com.onetech.adrewards.free.objects.AdRewardDTO;
import com.onetech.adrewards.free.utils.AdrewadsUtils;
import com.zuzu.db.store.SimpleStoreIF;

public class AdRewardModel implements AdRewardIF {
	private static AdRewardIF _instance;
	private static final Lock createLock = new ReentrantLock();
	private static final int STORE_EXPIRE = 5 * 60;

	public AdRewardModel() {
		getStoreAdapter();
	}

	public static AdRewardIF getInstance() {
		if (_instance == null) {
			createLock.lock();
			if (_instance == null) {
				_instance = new AdRewardModel();
			}
			createLock.unlock();
		}
		return _instance;
	}

	private SimpleStoreIF getStoreAdapter() {
		return AdrewadsUtils.getStoreAdapter(Cache.ADREWARD_NAME,
				OneTech_ApplicationContext.getContext(), Cache.ADREWARD_NUMBER);
	}

	public void setStore(String key, Object item) {
		if (item == null) {
			return;
		}
		Gson gson = new Gson();
		String temp = gson.toJson(item);
		this.getStoreAdapter().put(key, temp, STORE_EXPIRE);
	}

	@Override
	public Document parserAdRewardsXML(String url) {

		return null;
	}
	@Override
	public List<AdDTO2> getListAds(String url,String type,String page,String sortType){
		try {
			List<AdDTO2> result=new ArrayList<AdDTO2>();
			String key=Cache.ADREWARD_PAGE_KEY+type+page+String.valueOf(sortType);
			String json=getStoreAdapter().get(key);
			result=deserializeListAds(json);
			if(result!=null){
				return result;
			}
			AdrewadsUtils.checkUId();
			Bundle mBundle=new Bundle();
			APIRequestResult data = ZuZuHttpRequest.getInstance().getDataFromServer(url, mBundle);
			if (data == null) {
				return null;
			}
			result=parserListAds(data);
			if(result!=null && result.size()>0){
				setStore(key, result);
			}
			return result;
		} catch (Exception e) {
			return null;
		}
	}
	private List<AdDTO2> parserListAds(APIRequestResult data){
		List<AdDTO2> result=null;
		try {			
			if (data.error_code.equals("0") && data.data != null && !data.data.equals("")) {
				JSONObject jb=(JSONObject)data.data;
				JSONArray jArr=jb.getJSONArray("result");
				if(jArr!=null && jArr.length()>0){
					result=new ArrayList<AdDTO2>();
					for (int i = 0; i < jArr.length(); i++) {
						JSONObject temp=jArr.getJSONObject(i);
						AdDTO2 ad=deserialize2AdDTO(temp);
						if(ad!=null){
							result.add(ad);
						}
					}
				}
			}
		} catch (Exception e) {
		}
		return result;
	}
	private AdDTO2 deserialize2AdDTO(JSONObject jb){
		try {
			AdDTO2 result=new AdDTO2();
			result.att=jb.optString("attribute");
			result.btn_text=jb.optString("btn_text");
			result.coin=jb.optString("coin");
			result.img=jb.optString("img");
			result.id=jb.optString("id");
			result.is_app=jb.optString("is_app");
			result.is_max=jb.optString("is_max");
			result.is_video=jb.optString("is_video");
			result.name=jb.optString("name");
			result.remark=jb.optString("remark");
			result.sale_coin=jb.optString("sale_coin");
			
			result.short_desc=jb.optString("short_desc");
			result.source=jb.optString("source");
			result.url=jb.optString("url");
			result.charge_type=jb.optString("charge_type");
			result.wait_time=jb.optString("wait_time");
			
			result.is_rank=jb.optString("is_rank");
			result.is_rec=jb.optString("is_rec");
			result.start_date=jb.optString("start_date");
			result.charge_cate=jb.optString("charge_cate");
			result.rec_cate=jb.optString("rec_cate");
			result.camp_cate=jb.optString("camp_cate");
			result.icon_mark=jb.optString("icon_mark");
			result.rec_text=jb.optString("rec_text");
			return result;
		} catch (Exception e) {
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	private List<AdDTO2> deserializeListAds(String json) {
		List<AdDTO2> result = null;
		if (json == null || json.equals(""))
			return result;
		try {
			result = new ArrayList<AdDTO2>();
			Gson gson = new Gson();
			Type listType = new TypeToken<List<AdDTO2>>() {
			}.getType();
			result = (List<AdDTO2>) gson.fromJson(json, listType);
		} catch (Exception e) {
			return null;
		}
		return result;
	}
	@Override
	public AdRewardDTO getAds(String url,String type,String page,String sortType) {
		try {
			String key=Cache.ADREWARD_PAGE_KEY+type+page+String.valueOf(sortType);
			//Log.e("ARURL", type+":"+url);
			String json=getStoreAdapter().get(key);
			AdRewardDTO result=deserializeInteger(json);
			if(result!=null){
				return result;
			}
			String data = ZuZuHttpRequest.getStringAdRewardsXMLFromURL(url);
			if (data == null) {
				return null;
			}
			Document dom = getDomElement(data);
			if (dom == null) {
				return null;
			}
			result= parserDom(dom);
			if(result.getList_view()!=null && result.getList_view().size()>0){
				result = filterAdsBaseOnType(result, type);
				setStore(key, result);
			}
			return result;
		} catch (Exception e) {
		}
		return null;
	}
	public AdRewardDTO filterAdsBaseOnType(AdRewardDTO data,String type){
		//all,appli,au,purchase,registerfree,siteaccess
		try {
			List<AdDTO> result=new ArrayList<AdDTO>();
			
			if(type.trim().equals("appli")){
				//is_app=1 & charge_type=2	
				for (int i = 0; i < data.getList_view().size(); i++) {
					AdDTO temp=data.getList_view().get(i);
					if(temp.getCharge_tpe().trim().equals("2")){
						result.add(temp);
					}
				}
				data.setList_view(result);
			}else{
				if(type.trim().equals("registerfree")){
					//action_cate_id=9 & charge_type=2	
					for (int i = 0; i < data.getList_view().size(); i++) {
						AdDTO temp=data.getList_view().get(i);
						if(temp.getCharge_tpe().trim().equals("2")){
							result.add(temp);
						}
					}
					data.setList_view(result);
				}
			}
//				else{
//					if(type.trim().equals("purchase")){
//						///charge_type=1,3	
//						for (int i = 0; i < data.getList_view().size(); i++) {
//							AdDTO temp=data.getList_view().get(i);
//							if(temp.getCharge_tpe().trim().equals("1") || temp.getCharge_tpe().trim().equals("3")){
//								result.add(temp);
//							}
//						}
//						data.setList_view(result);
//					}else{
//						if(type.trim().equals("siteaccess")){
//							//is_app=0 & charge_type=2	
//							for (int i = 0; i < data.getList_view().size(); i++) {
//								AdDTO temp=data.getList_view().get(i);
//								if(temp.getIs_app().trim().equals("0") && temp.getCharge_tpe().trim().equals("2")){
//									result.add(temp);
//								}
//							}
//							data.setList_view(result);
//						}
//					}
//				}
//			}
			return data;
		} catch (Exception e) {
			return null;
		}	
		
	}
	private AdRewardDTO deserializeInteger(String json) {
		AdRewardDTO result = null;
		if (json == null || json.equals(""))
			return result;
		try {
			result = new AdRewardDTO();
			Gson gson = new Gson();
			Type listType = new TypeToken<AdRewardDTO>() {
			}.getType();
			result = (AdRewardDTO) gson.fromJson(json, listType);
		} catch (Exception e) {
			return null;
		}
		return result;
	}
	private AdRewardDTO parserDom(Document dom) {
		try {
			
			Element element = dom.getDocumentElement();
			AdRewardDTO result = new AdRewardDTO();
			List<AdDTO> listAds = new ArrayList<AdDTO>();
			result.setTotal_cnt(Integer.valueOf(getValue(element,
					AdRewardKey.total_cnt)));
			result.setM_owner_id(getValue(element, AdRewardKey.m_owner_id));

			NodeList list_view = element
					.getElementsByTagName(AdRewardKey.list_view);
			NodeList adList = list_view.item(0).getChildNodes();

			for (int i = 0; i < adList.getLength(); i++) {
				Node cNode = adList.item(i);
				if (cNode != null && cNode.getNodeName().equals(AdRewardKey.ad)) {
					//Log.e("AD NODE", "name: AD faw fwfw wfwfwfawawafwfwaf f");
					AdDTO ad=new AdDTO();
					if (cNode instanceof Element) {
						NodeList childNodes = cNode.getChildNodes();
						for (int j = 0; j < childNodes.getLength(); j++) {
							Node cNode2 = childNodes.item(j);
							if (cNode2 instanceof Element) {
								Node lNode = cNode2.getLastChild();
								if (lNode != null) {
									String nodeValue = lNode.getTextContent().trim();
									String  nodeName = cNode2.getNodeName();
									if (nodeName != null) {
										if(nodeName.equals(AdRewardKey.c_id)){
											ad.setC_id(nodeValue);
										}else{
											if(nodeName.equals(AdRewardKey.c_owner_id)){
												ad.setC_owner_id(nodeValue);
											}else{
												if(nodeName.equals(AdRewardKey.content_name)){
													ad.setContent_name(nodeValue);
												}else{
													if(nodeName.equals(AdRewardKey.career)){
														ad.setCareer(nodeValue);
													}else{
														if(nodeName.equals(AdRewardKey.banner_text_1)){
															ad.setBanner_text_1(nodeValue);
														}else{
															if(nodeName.equals(AdRewardKey.banner_img_1)){
																ad.setBanner_img_1(nodeValue);
															}else{
																if(nodeName.equals(AdRewardKey.banner_img_2)){
																	ad.setBanner_img_2(nodeValue);
																}else{
																	if(nodeName.equals(AdRewardKey.banner_img_alt)){
																		ad.setBanner_img_alt(nodeValue);
																	}else{
																		if(nodeName.equals(AdRewardKey.content_exp)){
																			ad.setContent_exp(nodeValue);
																		}else{
																			if(nodeName.equals(AdRewardKey.max_point)){
																				ad.setMax_point(nodeValue);
																			}
																			else{
																				if(nodeName.equals(AdRewardKey.attribute)){
																					ad.setAttribute(nodeValue);
																				}else{
																					if(nodeName.equals(AdRewardKey.scheme)){
																						ad.setScheme(nodeValue);
																					}else{
																						if(nodeName.equals(AdRewardKey.appli_url)){
																							ad.setAppli_url(nodeValue);
																						}else{
																							if(nodeName.equals(AdRewardKey.platform)){
																								ad.setPlatform(nodeValue);
																							}
																							else{
																								if(nodeName.equals(AdRewardKey.charge_type)){
																									ad.setCharge_type(nodeValue);
																								}else{
																									if(nodeName.equals(AdRewardKey.charge_exp)){
																										ad.setCharge_exp(nodeValue);
																									}else{
																										if(nodeName.equals(AdRewardKey.count_type_for_user)){
																											ad.setCount_type_for_user(nodeValue);
																										}else{
																											if(nodeName.equals(AdRewardKey.ad_tag_of_point_back)){
																												ad.setAd_tag_of_point_back(nodeValue);
																											}else{
																												if(nodeName.equals(AdRewardKey.ad_id)){
																													ad.setAd_id(nodeValue);
																												}else{
																													if(nodeName.equals(AdRewardKey.content_manage_category)){
																														ad.setContent_manage_category(nodeValue);
																													}else{
																														if(nodeName.equals(AdRewardKey.has_video)){
																															ad.setHas_video(nodeValue);
																														}else{
																															if(nodeName.equals(AdRewardKey.action_cate_id)){
																																ad.setAction_cate_id(nodeValue);
																															}
																															else{
																																if(nodeName.equals(AdRewardKey.is_app)){
																																	ad.setIs_app(nodeValue);
																																}else{
																																	if(nodeName.equals(AdRewardKey.pb_wait_time)){
																																		ad.setPb_wait_time(nodeValue);
																																	}	
																																}	
																															}	
																														}		
																													}		
																												}	
																											}
																										}																										
																									}																									
																								}																								
																							}
																						}
																					}
																				}
																			}
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
					if(ad.getC_id()!=null && ad.getC_id().length()>0){
						listAds.add(ad);
					}
				}
			}			
			result.setList_view(listAds);					
			return result;
		} catch (Exception e) {
			return null;
		}

	}


	public Document getDomElement(String xml) {
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			doc = db.parse(is);

		} catch (ParserConfigurationException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (SAXException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (IOException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		}
		// return DOM
		return doc;
	}

	public String getValue(Element item, String str) {
		NodeList n = item.getElementsByTagName(str);
		return this.getElementValue(n.item(0));
	}

	public final String getElementValue(Node elem) {
		Node child;
		if (elem != null) {
			if (elem.hasChildNodes()) {
				for (child = elem.getFirstChild(); child != null; child = child
						.getNextSibling()) {
					if (child.getNodeType() == Node.TEXT_NODE) {
						return child.getNodeValue();
					}
				}
			}
		}
		return "";
	}

	@Override
	public void clearAllData() {
		this.getStoreAdapter().removeAll();		
	}
}
